﻿#include "WidgetComServer.h"
#include <QFormLayout>
#include <QLabel>
#include <QInputDialog>
#include <QMessageBox>

#pragma execution_character_set("utf-8")
WidgetComServer::WidgetComServer(const QString &title, QWidget *parent)
    : QGroupBox(title,parent)
{
    setupUI();
    initConnection();
    mMapComServer.clear();
}

void WidgetComServer::addComServer(TcpServer *server)
{
    if(mMapComServer.contains(server->mConfig.name))
        return;
    mMapComServer.insert(server->mConfig.name, server);
    cbboxComNameList->addItem(server->mConfig.name);
    cbboxComNameList->setCurrentText(server->mConfig.name);
    connect(server, &TcpServer::sigStateChanged, this, [&](const ComState& state){
        if(cbboxComNameList->currentText() == mMapComServer.value(cbboxComNameList->currentText())->mConfig.name){
            txtedtDataRev->append(TcpServer::mapServerStateLabel.value(state));
        }
    });
    connect(server, &TcpServer::sigReceiveData, this, [&](const QByteArray& data){
        if(cbboxComNameList->currentText() == mMapComServer.value(cbboxComNameList->currentText())->mConfig.name){
            if(chkboxIsDisplayData->isChecked()){
                if(chkboxIsDisplayHex->isChecked()){
                    txtedtDataRev->append(data.toHex().toUpper());
                } else {
                    txtedtDataRev->append(data.data());
                }
            }
        }
    });
    connect(server, &TcpServer::sigMsg, this, [&](const QString& str){
        if(cbboxComNameList->currentText() == mMapComServer.value(cbboxComNameList->currentText())->mConfig.name){
            txtedtDataRev->append(str);
        }
    });
    connect(this, &WidgetComServer::sigConfigChanged, server, &TcpServer::onConfigChanged);
    connect(this, &WidgetComServer::sigWriteData, server, QOverload<const QString&>::of(&TcpServer::onWrite));
}

void WidgetComServer::setupUI()
{
    mLayout = new QHBoxLayout();
    this->setLayout(mLayout);
    setupConfigUI();
    setupSendRev();
}

void WidgetComServer::setupConfigUI()
{

    pbtnAddOne = new QPushButton("添加");
    pbtnDeleteOne = new QPushButton("删除");
    pbtnApplyPLC = new QPushButton("应用");
    cbboxComNameList = new QComboBox();

    QFormLayout* fLayout = new QFormLayout();
    mLayout->addLayout(fLayout);

    QHBoxLayout* hLayout = new QHBoxLayout();
    fLayout->addRow(hLayout);
    hLayout->addWidget(pbtnAddOne);
    hLayout->addWidget(pbtnDeleteOne);
    hLayout->addWidget(pbtnApplyPLC);
    fLayout->addRow("通讯列表", cbboxComNameList);
    {
        //网口区域
        wgtSocketConfig = new QWidget();
        fLayout->addRow(wgtSocketConfig);
        QFormLayout* fSocketLayout = new QFormLayout();
        wgtSocketConfig->setLayout(fSocketLayout);
        ledtOpponentIP = new QLineEdit("127.0.0.1");
        spboxOpponentPort = new QSpinBox();
        ledtLocalIP = new QLineEdit("127.0.0.1");
        spboxLocalPort = new QSpinBox();

        spboxOpponentPort->setRange(0,100000);
        spboxLocalPort->setRange(0,100000);
        spboxOpponentPort->setValue(5000);
        spboxLocalPort->setValue(6000);

        fSocketLayout->addRow("本地IP", ledtLocalIP);
        fSocketLayout->addRow("本地端口", spboxLocalPort);
        fSocketLayout->addRow("对方IP", ledtOpponentIP);
        fSocketLayout->addRow("对方端口", spboxOpponentPort);
    }
    chkboxSendHex = new QCheckBox("发送十六进制");
    fLayout->addRow(chkboxSendHex);
}

void WidgetComServer::setupSendRev()
{
        //接收区
    chkboxIsDisplayData = new QCheckBox("显示数据");
    chkboxIsDisplayHex = new QCheckBox("显示十六进制");
    pbtnClear = new QPushButton("清空");
    txtedtDataRev = new QTextEdit();

    txtedtDataSend = new QTextEdit();
    pbtnSendData = new QPushButton("发送");

    QVBoxLayout* vLayout0 = new QVBoxLayout();
    {
        QHBoxLayout* hLayout1 = new QHBoxLayout();
        hLayout1->addWidget(chkboxIsDisplayData);
        hLayout1->addWidget(chkboxIsDisplayHex);
        hLayout1->addWidget(pbtnClear);
        vLayout0->addLayout(hLayout1);
    }
    vLayout0->addWidget(txtedtDataRev);
    vLayout0->addWidget(txtedtDataSend);
    vLayout0->addWidget(pbtnSendData);
    mLayout->addLayout(vLayout0);
}

void WidgetComServer::initConnection()
{
    connect(pbtnAddOne, &QAbstractButton::clicked, this, [&](){
        QString name = QInputDialog::getText(nullptr,"输入新增通信名称","名称");
        if(name.isEmpty())
            return;
        TcpComConfig config = getConfig();
        config.name = name;
        emit sigAddOne(config);
    });
    connect(pbtnDeleteOne, &QAbstractButton::clicked, this, [&](){
        if(!(cbboxComNameList->count() > 0))
            return;
        QMessageBox msgBox(QMessageBox::Question, "提示","确认删除此通信吗?",
                           QMessageBox::Yes | QMessageBox::No);
        msgBox.button(QMessageBox::Yes)->setText("确认");
        msgBox.button(QMessageBox::No)->setText("取消");
        if(QMessageBox::No == msgBox.exec())
            return;
        mMapComServer.remove(cbboxComNameList->currentText());
        emit sigDeleteOne(cbboxComNameList->currentText());
        cbboxComNameList->removeItem(cbboxComNameList->currentIndex());
    });
    connect(pbtnApplyPLC, &QAbstractButton::clicked, this, &WidgetComServer::onSaveConfig);
    connect(cbboxComNameList, QOverload<int>::of(&QComboBox::currentIndexChanged), this, &WidgetComServer::onComSelectChanged);
    connect(pbtnClear, &QAbstractButton::clicked, this, [&](){
        txtedtDataRev->clear();
    });

    connect(pbtnSendData, &QAbstractButton::clicked, this, [&](){
        QString txtSend = txtedtDataSend->toPlainText();
        emit sigWriteData(txtSend);
    });
}

TcpComConfig WidgetComServer::getConfig()
{
    TcpComConfig config;
    config.name = config.name;
    config.mOpponentIP = ledtOpponentIP->text();
    config.mOpponentPort = spboxOpponentPort->value();
    config.mLocalIP = ledtLocalIP->text();
    config.mLocalPort = spboxLocalPort->value();
    config.mIsSendHex = chkboxSendHex->isChecked();
    return config;
}

void WidgetComServer::onSaveConfig()
{
    TcpComConfig config = getConfig();
    emit sigConfigChanged(config);
}

void WidgetComServer::onComSelectChanged(const int& index)
{
    if(index < 0)
        return;
    TcpComConfig config = mMapComServer.value(cbboxComNameList->currentText())->mConfig;
    chkboxSendHex->setChecked(config.mIsSendHex);
    ledtOpponentIP->setText(config.mOpponentIP);
    spboxOpponentPort->setValue(config.mOpponentPort);
    ledtLocalIP->setText(config.mLocalIP);
    spboxLocalPort->setValue(config.mLocalPort);

}
